package com.kinsin.kinsinutil

import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

@RunWith(AndroidJUnit4::class)
class NeverCrashTest {

    private lateinit var originalHandler: Thread.UncaughtExceptionHandler
    private var mainExceptionTriggered = false
    private var uncaughtExceptionTriggered = false

    // 将原来的Boolean类型改为Int计数器
    private var mainExceptionCount = 0
    private var uncaughtExceptionCount = 0

    @Before
    fun setup() {
        // 保存原始异常处理器
        originalHandler = Thread.getDefaultUncaughtExceptionHandler()
        // 重置计数器
        mainExceptionCount = 0
        uncaughtExceptionCount = 0

        NeverCrash
            .setDebugMode(true)
            .setMainCrashHandler { _, _ ->
                mainExceptionTriggered = true
                mainExceptionCount++
            }
            .setUncaughtCrashHandler { _, _ ->
                uncaughtExceptionTriggered = true
                uncaughtExceptionCount++
            }
            .register()
    }

    @After
    fun tearDown() {
        // 恢复原始异常处理器
        Thread.setDefaultUncaughtExceptionHandler(originalHandler)
    }

    @Test
    fun testMainThreadCrashHandling() {
        val latch = CountDownLatch(1)

        // 在主线程抛出异常
        Handler(Looper.getMainLooper()).post {
            throw TestException("Main thread test exception")
        }

        // 等待处理完成
        latch.await(2, TimeUnit.SECONDS)

        assertTrue(mainExceptionTriggered)
    }

    @Test
    fun testBackgroundThreadCrashHandling() {
        val latch = CountDownLatch(1)

        Thread {
            throw TestException("Background thread test exception")
        }.apply {
            start()
            join()
        }

        latch.await(2, TimeUnit.SECONDS)

        assertTrue(uncaughtExceptionTriggered)
    }

    @Test
    fun testDebugModeLogging() {
        // 注意：原生测试无法直接验证Log输出，这里验证调试模式开关
        assertTrue(NeverCrash.getDebugMode())

        NeverCrash.setDebugMode(false)
        assertFalse(NeverCrash.getDebugMode())
    }

    @Test
    fun testCustomHandlers() {
        val testMainHandler = NeverCrash.MainCrashHandler { _, _ -> }
        val testUncaughtHandler = NeverCrash.UncaughtCrashHandler { _, _ -> }

        NeverCrash
            .setMainCrashHandler(testMainHandler)
            .setUncaughtCrashHandler(testUncaughtHandler)

        assertTrue(NeverCrash.getMainCrashHandler() === testMainHandler)
        assertTrue(NeverCrash.getUncaughtCrashHandler() === testUncaughtHandler)
    }

    @Test
    fun testFrequentExceptionsStability() {
        val iterations = 50 // 测试次数
        val latch = CountDownLatch(iterations * 2) // 主线程和子线程各50次
        var mainExceptionCount = 0
        var uncaughtExceptionCount = 0

        // 重置计数器
        NeverCrash
            .setMainCrashHandler { _, _ -> mainExceptionCount++ }
            .setUncaughtCrashHandler { _, _ -> uncaughtExceptionCount++ }

        // 主线程高频异常
        repeat(iterations) { i ->
            Handler(Looper.getMainLooper()).post {
                try {
                    throw TestException("Main thread stress test $i")
                } finally {
                    latch.countDown()
                }
            }
        }

        // 子线程高频异常
        repeat(iterations) { i ->
            Thread {
                try {
                    throw TestException("Background thread stress test $i")
                } finally {
                    latch.countDown()
                }
            }.apply {
                start()
                join() // 确保线程执行完成
            }
        }

        // 等待所有异常处理完成（增加等待时间）
        assertTrue("未在指定时间内完成所有异常处理", latch.await(15, TimeUnit.SECONDS))

        // 验证所有异常都被捕获
        assertEquals("主线程异常捕获次数不匹配", iterations, mainExceptionCount)
        assertEquals("子线程异常捕获次数不匹配", iterations, uncaughtExceptionCount)

        // 后续验证（验证功能是否仍然可用）
        val postLatch = CountDownLatch(1)
        Handler(Looper.getMainLooper()).post {
            // 测试主线程是否仍然可以正常工作
            Log.d("NeverCrashTest", "Main thread still working")
            postLatch.countDown()
        }
        assertTrue("主线程后续任务执行失败", postLatch.await(1, TimeUnit.SECONDS))

        // 测试新线程是否仍然可以正常工作
        val threadLatch = CountDownLatch(1)
        Thread {
            Log.d("NeverCrashTest", "New thread still working")
            threadLatch.countDown()
        }.start()
        assertTrue("子线程后续任务执行失败", threadLatch.await(1, TimeUnit.SECONDS))
    }

    private class TestException(message: String) : RuntimeException(message)
}